﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace Gmantis.Controls.DataGrid
{
    public class DataGridCellsPanel : RecyclingPanel
    {
        // Fields
        private DataGridVerticalFreezingSeparatorPresenter _verticalFreezingSeparatorPresenter;

        // Methods
        protected override Size ArrangeOverride(Size finalSize)
        {
            if (this.RowPresenter.ViewRow != null)
            {
                double width = finalSize.Width;
                double frozenLeftWidth = this.View.ScrollManager.FrozenLeftWidth;
                double leftOffset = frozenLeftWidth + this.View.Model.VerticalFreezingSeparatorWidth;
                double rightOffset = width - this.View.ScrollManager.FrozenRightWidth;
                foreach (UIElement element in base.Children)
                {
                    DataGridCellPresenter presenter = element as DataGridCellPresenter;
                    if ((presenter != null) && !presenter.IsCollected)
                    {
                        ViewColumn viewColumn = presenter.ViewColumn;
                        if (viewColumn != null)
                        {
                            Size mergedSize = presenter.MergedSize;
                            double presenterRenderWidth = mergedSize.Width;
                            double height = mergedSize.Height;
                            if (viewColumn.Column.IsFrozen)
                            {
                                Canvas.SetZIndex(presenter, 0x3e8);
                                presenter.Clip = null;
                            }
                            else
                            {
                                Canvas.SetZIndex(presenter, this.VisibleColumns.LastVisibleItem - viewColumn.Column.DisplayIndex);
                                base.ClipPresenterVertically(presenter, presenterRenderWidth, height, leftOffset, rightOffset, viewColumn.Offset);
                            }
                            presenter.Arrange(new Rect(viewColumn.Offset, 0.0, presenterRenderWidth, height));
                        }
                        else
                        {
                            presenter.Arrange(new Rect(0.0, 0.0, this.View.GetRenderLeadingColumnWidth(), finalSize.Height));
                        }
                    }
                    DataGridVerticalFreezingSeparatorPresenter presenter2 = element as DataGridVerticalFreezingSeparatorPresenter;
                    if (presenter2 != null)
                    {
                        presenter2.Arrange(new Rect(frozenLeftWidth, 0.0, this.View.Model.VerticalFreezingSeparatorWidth, finalSize.Height));
                    }
                }
            }
            return finalSize;
        }

        internal void EditCompleted(ViewColumn viewColumn)
        {
            if (this.IsColumnVisible(viewColumn))
            {
                foreach (UIElement element in base.Children)
                {
                    DataGridCellPresenter presenter = element as DataGridCellPresenter;
                    if ((presenter != null) && (presenter.ViewColumn == viewColumn))
                    {
                        presenter.UpdateEditingCell();
                        break;
                    }
                }
            }
        }

        internal DataGridVerticalFreezingSeparatorPresenter GetVerticalFreezingSeparatorPresenter(Func<DataGridVerticalFreezingSeparatorPresenter> creator)
        {
            if (this._verticalFreezingSeparatorPresenter == null)
            {
                this._verticalFreezingSeparatorPresenter = creator();
                base.Children.Add(this._verticalFreezingSeparatorPresenter);
            }
            return this._verticalFreezingSeparatorPresenter;
        }

        private bool IsColumnVisible(ViewColumn viewColumn)
        {
            int columnDisplayIndex = viewColumn.ColumnDisplayIndex;
            return ((columnDisplayIndex < this.View.Model.FrozenColumnCount) || ((columnDisplayIndex >= this.VisibleColumns.FirstVisibleItem) && (columnDisplayIndex <= this.VisibleColumns.LastVisibleItem)));
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            double num = 0.0;
            double columnOffset = 0.0;
            if ((this.RowPresenter != null) && (this.RowPresenter.ViewRow != null))
            {
                columnOffset = this.ValidFillParameters.ColumnOffset;
                ViewRow viewRow = this.RowPresenter.ViewRow;
                DataGridView view = this.View;
                if (!double.IsInfinity(availableSize.Width))
                {
                    int num3;
                    int num4;
                    view.ScrollManager.GetCurrentHorizontalBounds(availableSize.Width, out num3, out num4);
                    this.RemoveUnusedChildren(num3, num4);
                }
                DataGridVisibleItems<DataGridColumn> visibleColumns = this.VisibleColumns;
                visibleColumns.ClearVisibleItems();
                if (this._verticalFreezingSeparatorPresenter != null)
                {
                    base.Hide(this._verticalFreezingSeparatorPresenter);
                }
                if (view.DataGrid.ShowLeftFreezingSeparator)
                {
                    if (viewRow.Row.ShowVerticalFreezingSeparator)
                    {
                        DataGridVerticalFreezingSeparatorPresenter verticalFreezingSeparatorPresenter = viewRow.GetVerticalFreezingSeparatorPresenter();
                        base.Show(verticalFreezingSeparatorPresenter);
                        verticalFreezingSeparatorPresenter.Measure(new Size(view.Model.VerticalFreezingSeparatorWidth, double.PositiveInfinity));
                    }
                    columnOffset += view.Model.VerticalFreezingSeparatorWidth;
                }
                foreach (ViewColumn column in view.GetFrozenAndScrollingColumns(this.ValidFillParameters.ColumnIndex, this.ValidFillParameters.HorizontalDirection))
                {
                    if (availableSize.Width == 0.0)
                    {
                        break;
                    }
                    visibleColumns.AddVisibleItem(column.Column);
                    DataGridCellPresenter cellPresenter = viewRow.GetCellPresenter(column, true);
                    if (cellPresenter != null)
                    {
                        cellPresenter.MinWidth = column.MinWidth;
                        cellPresenter.Measure(new Size(column.MeasureWidth, viewRow.MeasureHeight));
                        column.DesiredWidth = Math.Max(column.DesiredWidth, cellPresenter.DesiredSize.Width);
                        if (cellPresenter.DesiredSize.Height > num)
                        {
                            this.MaxHeightColumnDisplayIndex = cellPresenter.Column.DisplayIndex;
                        }
                        num = Math.Max(num, cellPresenter.DesiredSize.Height);
                    }
                    columnOffset += column.MinRenderWidth;
                    if (columnOffset >= view.ScrollManager.AvailableCellsAreaWidth)
                    {
                        break;
                    }
                }
                this.RemoveUnusedChildren(visibleColumns.FirstVisibleItem, visibleColumns.LastVisibleItem);
            }
            return new Size(Math.Max(0.0, Math.Min(availableSize.Width, columnOffset)), num);
        }

        private void RemoveUnusedChildren(int firstColumnIndex, int lastColumnIndex)
        {
            foreach (UIElement element in new List<UIElement>(base.Children.GetTypedUIElementCollectionWrapper()))
            {
                DataGridCellPresenter child = element as DataGridCellPresenter;
                if ((child != null) && !child.IsCollected)
                {
                    bool flag = false;
                    if ((child.ViewColumn == null) || (child.ViewRow == null))
                    {
                        flag = true;
                    }
                    else
                    {
                        ViewColumn viewColumn = child.ViewColumn;
                        int columnDisplayIndex = viewColumn.ColumnDisplayIndex;
                        if ((((columnDisplayIndex < firstColumnIndex) || (columnDisplayIndex > lastColumnIndex)) && !viewColumn.Column.IsFrozen) || (viewColumn.Column.Visibility == Visibility.Collapsed))
                        {
                            flag = true;
                        }
                    }
                    if (flag)
                    {
                        this.RemoveChild(child);
                    }
                }
            }
        }

        internal FrameworkElement SetEditingCell(ViewColumn viewColumn)
        {
            if (this.IsColumnVisible(viewColumn))
            {
                foreach (UIElement element in base.Children)
                {
                    DataGridCellPresenter presenter = element as DataGridCellPresenter;
                    if ((presenter != null) && (presenter.ViewColumn == viewColumn))
                    {
                        return presenter.UpdateEditingCell();
                    }
                }
            }
            return null;
        }

        public void UpdateCurrentCell()
        {
            foreach (UIElement element in base.Children)
            {
                DataGridCellPresenter presenter = element as DataGridCellPresenter;
                if ((presenter != null) && !presenter.IsCollected)
                {
                    presenter.UpdateCurrentCell();
                }
            }
        }

        public void UpdateLines()
        {
            foreach (UIElement element in base.Children)
            {
                DataGridCellPresenter presenter = element as DataGridCellPresenter;
                if ((presenter != null) && !presenter.IsCollected)
                {
                    presenter.UpdateLines();
                }
            }
        }

        public void UpdateMouseOver()
        {
            foreach (UIElement element in base.Children)
            {
                DataGridCellPresenter presenter = element as DataGridCellPresenter;
                if ((presenter != null) && !presenter.IsCollected)
                {
                    presenter.UpdateMouseOver();
                }
            }
        }

        public void UpdateSelection()
        {
            foreach (UIElement element in base.Children)
            {
                DataGridCellPresenter presenter = element as DataGridCellPresenter;
                if ((presenter != null) && !presenter.IsCollected)
                {
                    presenter.UpdateSelection();
                }
            }
        }

        public void UpdateValidationState()
        {
            foreach (UIElement element in base.Children)
            {
                DataGridCellPresenter presenter = element as DataGridCellPresenter;
                if ((presenter != null) && !presenter.IsCollected)
                {
                    presenter.UpdateValidationState();
                }
            }
        }

        // Properties
        internal int MaxHeightColumnDisplayIndex { get; set; }

        public DataGridRowPresenter RowPresenter { get; internal set; }

        private FillParameters ValidFillParameters
        {
            get
            {
                return this.View.ScrollManager.ValidFillParameters;
            }
        }

        internal DataGridView View
        {
            get
            {
                return this.RowPresenter.View;
            }
        }

        internal ViewRow ViewRow
        {
            get
            {
                return this.RowPresenter.ViewRow;
            }
        }

        internal DataGridVisibleItems<DataGridColumn> VisibleColumns
        {
            get
            {
                return this.View.Viewport.VisibleColumns;
            }
        }

        internal DataGridVisibleItems<DataGridRow> VisibleRows
        {
            get
            {
                return this.View.Viewport.VisibleRows;
            }
        }
    }
}
